﻿using FileSC.Configs;
using FileSC.DB.Database;
using FileSC.DB.Entities;
using FileSC.FileSystem;
using FileSC.NetLIB;
using FileSC.WEBService.Db;
using FileSC.WEBService.Dto;
using FileSC.WEBService.Helper;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FileSC.WEBService.Client
{
    internal class MyHttp
    {
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task<string> DownloadFile(DownloadFileInput input, bool recover)
        {
            var client = new NasApi(input.Uri);
            using (var responseResult = await client.Get(input.Uri))
            {
                var response = responseResult.Response;

                var filename = AppConfig.Text("默认文件名");
                if (string.IsNullOrEmpty(input.Path))
                {
                    filename = Path.GetFileName(input.Path);
                }
                if (AppConfig.YesOrNo("解析文件名"))
                {
                    var header_key = AppConfig.Text("文件名解析方式");
                    //数据读完成
                    if (response.Headers.ContainsKey(header_key))
                    {
                        var disposition = response.Headers[header_key];
                        var d = new System.Net.Mime.ContentDisposition(disposition);
                        filename = d.FileName;
                        if (AppConfig.YesOrNo("解码文件名"))
                        {
                            filename = System.Web.HttpUtility.UrlDecode(filename, Encoding.UTF8);
                        }
                    }
                }

                var basePath = PathHelper.GetDownloadCacheFile(input.Path);
                var file_allpath = Path.Combine(basePath, input.Id.ToString());
                var out_path = Path.Combine(basePath, filename);
                var file_totalsize = response.ContentLength;
                DownloadJobInfo info;
                using (var db = new DownloadJobDB())
                {
                    info = db.Update(input.Id, i =>
                    {
                        i.FileSize = file_totalsize;
                        i.DownloadSize = 0;
                        i.Message = "下载中";

                        return i;
                    });

                    var now = DateTime.Now.Second;
                    using (var file = System.IO.File.Open(file_allpath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                    {
                        await response.ReadCopyToAsync(file, (now_size) =>
                        {
                            db.SetDownloadSize(input.Id, now_size);
                        });

                    }
                    info.DownloadSize = file_totalsize;
                    info.Message = string.Empty;
                    db.Update(info);
                    db.ClearDownloadSize(input.Id);
                }
                if (AppConfig.YesOrNo("下载后添加哈希标记"))
                {
                }

                if (File.Exists(out_path))
                {
                    File.Delete(out_path);
                }
                File.Move(file_allpath, out_path);
                if (AppConfig.YesOrNo("立即打开文件"))
                {
                    OpenFile(file_allpath);
                }

                return file_allpath;
            }
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task UploadFile(UploadFileInput input, bool recover)
        {
            var client = new NasApi(input.ServerUrl);
            var content = new MultiDataContent();
            var path = Path.GetDirectoryName(input.RemotePath);
            path = path.Replace('\\', '/'); // 修正目录分隔符
            var filename = Path.GetFileName(input.RemotePath);
            content.AddContent("Path", path);
            content.AddContent("FileName", filename);
            var filesize = content.AddFileContent(Path.GetFileNameWithoutExtension(input.Path), input.Path);
            client.AddHeader("Authorization", input.Auth);
            client.AddContent(content);

            using (var db = new UploadJobDB())
            {
                db.Update(input.Id, info =>
                {
                    info.FileSize = filesize;
                    info.UploadSize = 0;
                    info.Message = "正在上传";
                    return info;
                });
                content.ProgressCallback += (string name, long now_size, long total_size) =>
                {
                    db.SetUploadSize(input.Id, now_size);
                };
                try
                {
                    using (var responseResult = await client.Post(input.ServerUrl + input.UploadApi)) // one day
                    {
                        var response = responseResult.Response;
                    }
                }
                catch (Exception ex)
                {
                    db.Update(input.Id, info =>
                    {
                        info.Message = ex.Message;
                        return info;
                    });
                }
            }
        }

        private static void Content_ProgressCallback(string name, long now_size, long total_size)
        {
            Console.WriteLine($"{name} {now_size} {total_size}");
        }

        public static async Task NewFolder(NewFolderInput input)
        {
            var client = new NasApi(input.ServerUrl);
            var path = input.Path.Replace('\\', '/').TrimEnd('/'); // 修正目录分隔符
            var content = new JsonContent();
            client.AddHeader("Authorization", input.Auth);
            content.Use(new
            {
                path = path,
                name = input.Name
            });
            client.AddContent(content);
            try
            {
                using (var responseResult = await client.Post(input.ServerUrl + input.Api)) // one day
                {
                    var response = responseResult.Response;
                }
            }
            catch (Exception ex)
            {
            }
        }
        /// <summary>
        /// 上传目录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task UploadPath(UploadPathInput input)
        {
            Console.WriteLine($"{input.Path} -> {input.RemotePath}");
            var tool = new PathTool(input.Path);

            var rpath_name = Path.GetFileName(input.RemotePath);
            await NewFolder(new NewFolderInput
            {
                ServerUrl = input.ServerUrl,
                Auth = input.Auth,
                Api = input.NewFolderApi,
                Path = input.RemotePath.Replace(rpath_name, ""),
                Name = rpath_name,
            });

            foreach (var dir in tool.ReadDirectories())
            {
                var file_path = PathTool.ToRelativePath(dir.FullName, input.Path);
                var remote_path = Path.Combine(input.RemotePath, file_path);
                remote_path = remote_path.Replace('\\', '/'); // 修正目录分隔符

                rpath_name = Path.GetDirectoryName(remote_path);
                await NewFolder(new NewFolderInput
                {
                    ServerUrl = input.ServerUrl,
                    Auth = input.Auth,
                    Api = input.NewFolderApi,
                    Path = remote_path.Replace(rpath_name, ""),
                    Name = rpath_name,
                });
            }

            foreach (var path in tool.ReadAllFiles())
            {
                var file_path = PathTool.ToRelativePath(path.FullName, input.Path);
                var remote_path = Path.Combine(input.RemotePath, file_path);
                remote_path = remote_path.Replace('\\', '/'); // 修正目录分隔符

                await UploadFile(new UploadFileInput
                {
                    Auth = input.Auth,
                    ServerUrl = input.ServerUrl,
                    UploadApi = input.UploadApi,
                    Path = path.FullName,
                    RemotePath = remote_path
                }, false);
            }
        }
        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="file_path"></param>
        public static void OpenFile(string file_path)
        {
            // 需要检测是否已经存在系统目录已打开， 仅置顶
            var cmd = $"\"{Path.GetFullPath(file_path)}\"";
            var tag = Path.GetExtension(file_path).ToLower().TrimStart('.');
            if (AppConfig.YesOrNo("不运行可执行文件"))
            {
                if (AppConfig.Array("可执行文件标识").Contains(tag))
                {
                    OpenFolder(file_path);
                    return;
                }
            }

            if (AppConfig.Array("文件管理器文件标识").Contains(tag))
            {
                System.Diagnostics.Process.Start("c:\\windows\\explorer.exe", cmd);
            }
            else
            {
                System.Diagnostics.Process.Start(cmd);
            }
        }

        public static async Task OpenFile(DownloadFileInput input, bool recover)
        {

            var file_path = await DownloadFile(input, false);
            if (!AppConfig.YesOrNo("立即打开文件"))
            {
                OpenFile(file_path);
            }
        }

        public static void OpenFolder(string path)
        {
            var cmd = $"\"{Path.GetDirectoryName(Path.GetFullPath(path))}\"";
            System.Diagnostics.Process.Start("c:\\windows\\explorer.exe", cmd);
        }
    }
}
